import { getZindex } from '../utils.js';

const closeSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 10.5858L14.8284 7.75736L16.2426 9.17157L13.4142 12L16.2426 14.8284L14.8284 16.2426L12 13.4142L9.17157 16.2426L7.75736 14.8284L10.5858 12L7.75736 9.17157L9.17157 7.75736L12 10.5858Z"></path></svg>'

const infoFillSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z"></path></svg>'

const checkboxCircleFillSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11.0026 16L6.75999 11.7574L8.17421 10.3431L11.0026 13.1716L16.6595 7.51472L18.0737 8.92893L11.0026 16Z"></path></svg>'

const errorWarningFillSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z"></path></svg>'

const questionFillSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM13 13.3551V14H11V12.5C11 11.9477 11.4477 11.5 12 11.5C12.8284 11.5 13.5 10.8284 13.5 10C13.5 9.17157 12.8284 8.5 12 8.5C11.2723 8.5 10.6656 9.01823 10.5288 9.70577L8.56731 9.31346C8.88637 7.70919 10.302 6.5 12 6.5C13.933 6.5 15.5 8.067 15.5 10C15.5 11.5855 14.4457 12.9248 13 13.3551Z"></path></svg>'

class ModalEffect {
    config = null
    container = null

    constructor(options) {
        // 合并参数
        this.initConfig(options)
        // 创建容器
        this.initContainer()
        // 计算内容
        this.initView()
        // 挂载容器
        this.mount()
        // 绑定事件
        this.initEvent()
        const { open } = this.config
        // 自动打开
        if (open) {
            this.open()
        }
    }

    initConfig(options = {}) {
        const {
            open = false,
            backdrop = false,
            closeable = false,
            title = '',
            closeText = '',
            okText = '',
            content = '',
            className = '',
            parentNode,
            valid,
            close,
            ok,
            bodyStyle,
            escapeClose = false,
            closeClass
        } = options
        const opts = {
            open,
            backdrop,
            closeable,
            title,
            closeText,
            okText,
            content,
            className: typeof className === 'string' ? className : '',
            parentNode,
            valid,
            close,
            ok,
            bodyStyle: typeof bodyStyle === 'string' ? bodyStyle : '',
            escapeClose,
            zIndex: getZindex(),
            closeClass: closeClass || '',
        }
        this.config = opts
    }
    initContainer() {
        const { className, zIndex } = this.config
        const el = document.createElement('div')
        el.className = `an-modal ${className}`.trim()
        el.setAttribute('data-modalid', zIndex)
        el.style.setProperty('--el-modal-zindex', zIndex)
        this.container = el
    }
    initView() {
        const {
            backdrop,
            closeable,
            title,
            closeText,
            okText,
            content,
            bodyStyle,
            closeClass,
        } = this.config
        let footer = []
        {
            if (closeText) {
                footer.push(`<button class="an-button an-button-close">${closeText}</an-button>`)
            }
            if (okText) {
                footer.push(`<button class="an-button an-button-ok" type="primary">${okText}</an-button>`)
            }
            if (footer.length) {
                footer = `<div class="an-modal-footer">${footer.join('')}</div>`
            }
        }
        const html = `
            ${backdrop ? `<div class="an-modal-backdrop"></div>` : ''}
            <div class="an-modal-wrapper">
                <div class="an-modal-main">
                    ${title ? `<div class="an-modal-header">${title}</div>` : ''}
                    <div class="an-modal-body" style="${bodyStyle}">
                        ${content}
                    </div>
                    ${footer}
                    ${closeable ? `<span class="an-modal-close ${closeClass}">${closeSvg}</span>` : ''}
                </div>
            </div>
        `
        this.container.innerHTML = html
    }
    initEvent() {
        const {
            backdrop,
            closeable,
            closeText,
            okText,
            valid,
            close,
            ok,
        } = this.config
        const closeCallback = () => {
            if (typeof valid === 'function') {
                if (!valid('close')) {
                    return
                }
            }
            this.emit(close)
            this.close()
        }
        const okCallback = () => {
            if (typeof valid === 'function') {
                if (!valid('ok')) {
                    return
                }
            }
            this.emit(ok)
            this.close()
        }
        if (backdrop) {
            this.bind(this.qs('.an-modal-backdrop'), 'click', closeCallback)
        }
        if (closeable) {
            this.bind(this.qs('.an-modal-close'), 'click', closeCallback)
        }
        if (closeText) {
            this.bind(this.qs('.an-button-close'), 'click', closeCallback)
        }
        if (okText) {
            this.bind(this.qs('.an-button-ok'), 'click', okCallback)
        }
    }
    mount() {
        // const that = this
        const { parentNode } = this.config
        if (parentNode) {
            parentNode.appendChild(this.container)
        } else {
            document.body.appendChild(this.container)
        }
        if (this.config.escapeClose) {
            document.addEventListener('keyup', this.escape.bind(this))
        }
    }
    unmount() {
        const { parentNode } = this.config
        if (parentNode) {
            parentNode.removeChild(this.container)
        } else {
            document.body.removeChild(this.container)
        }
        document.removeEventListener('keyup', this.escape.bind(this))
    }
    open() {
        this.container.setAttribute('open', '')
    }
    close() {
        this.container.removeAttribute('open')
    }
    escape(e) {
        const {
            valid,
            close,
        } = this.config
        const closeCallback = () => {
            if (typeof valid === 'function') {
                if (!valid('close')) {
                    return
                }
            }
            this.close()
            this.emit(close)
        }
        // console.log(e.key)
        //此处填写你的业务逻辑即可
        if (e.key.toLocaleLowerCase() === 'escape') {
            closeCallback()
        }
    }
    bind(el, eventName, eventHandler, options) {
        if (!el || !eventName || !eventHandler) {
            return
        }
        el.addEventListener(eventName, eventHandler, options)
    }
    unbind(el, eventName, eventHandler, options) {
        if (!el || !eventName || !eventHandler) {
            return
        }
        el.removeEventListener(eventName, eventHandler, options)
    }
    emit(fn, ...args) {
        if (typeof fn !== 'function') {
            return
        }
        fn.apply(null, args)
    }
    qs(selector) {
        return this.container.querySelector(selector)
    }
    qsa(selector) {
        return this.container.querySelectorAll(selector)
    }
}

export const modal = {
    open(options) {
        return new ModalEffect(options)
    },
    alert({ okText, content, ...options }) {
        return this.open({
            ...options,
            open: true,
            okText: okText || 'OK',
            content: `<div class="an-modal-message">
                <span class="an-modal-message-icon" style="color:var(--el-color-primary);">
                    ${infoFillSvg}
                </span>
                ${content}
            </div>`
        })
    },
    success({ okText, content, ...options }) {
        return this.open({
            ...options,
            open: true,
            okText: okText || 'OK',
            content: `<div class="an-modal-message">
                <span class="an-modal-message-icon" style="color:var(--el-color-success);">
                    ${checkboxCircleFillSvg}
                </span>
                ${content}
            </div>`
        })
    },
    error({ okText, content, ...options }) {
        return this.open({
            ...options,
            open: true,
            okText: okText || 'OK',
            content: `<div class="an-modal-message">
                <span class="an-modal-message-icon" style="color:var(--el-color-danger);">
                    ${errorWarningFillSvg}
                </span>
                ${content}
            </div>`
        })
    },
    confirm({ closeText, okText, content, ...options }) {
        return this.open({
            ...options,
            open: true,
            closeText: closeText || 'Close',
            okText: okText || 'OK',
            content: `<div class="an-modal-message">
                <span class="an-modal-message-icon" style="color:var(--el-color-warning);">
                    ${questionFillSvg}
                </span>
                ${content}
            </div>`
        })
    }
}
